﻿#include<boost/asio.hpp>
#include<memory>
#include<type_traits>
#include<stdexcept>
#include"./RpcClient.hpp"
#include"../Base/Network/Client.hpp"
#include"../Base/Network/Session.hpp"
#include"../Base/Network/BinaryDispatch.hpp"
#include"../Base/Network/NetworkDef.hpp"


namespace SC_SUN
{
    using namespace boost::asio;
    using namespace MMFNetwork;

    RpcClient::RpcClient(const std::string& remoteIp, uint16_t remotePort, const std::function<void(bool)>& statasHandler)
        : mRemoteIp(remoteIp)
        , mRemotePort(remotePort)
        , mStatusHandler(statasHandler)
    {
        //添加序列化缓冲池
        for (int i = 0; i < 32; i++)
        {
            std::vector<char> buff(MMFNetwork::MAX_MESSAGE_BUFFER_SIZE);
            mSerialInPool.PushObject(buff);
        }
    }

    RpcClient::~RpcClient()
    {

    }
    
    bool RpcClient::Start()
    {
        //创建消息分发器
        mDispatcher = std::make_shared<MMFNetwork::BinaryDispatch>([this](const std::shared_ptr<Session>& session, MMFMessageHeader* pkg){
            //默认消息处理函数
            //需要对没有监听的消息进行错误处理
            throw std::logic_error("unhandled network message!");
        });

        try
        {
            MMFInetFamily family = MMFInetFamily::V4;
            ip::address addr = ip::address::from_string(mRemoteIp);
            if (addr.is_v6())
                family = MMFNetwork::MMFInetFamily::V6;

            uint32_t bufferSize = 128u * 1024u;   //每个session 128KB的缓存空间,这里只有有command信息，不会太长

            //出错的回调函数
            auto clientErrorHandler =  [this](boost::system::error_code err){

            };

            //状态回调函数
            auto clientStatusHandler = [this](Status status){
                if(status == Status::Connected)
                    mStatusHandler(true);
                else 
                    mStatusHandler(false);
            };

            //异步收回调
            auto clientAsyncHandler = [this](void* buffer, bool state){

            };

            //收报回调
            auto clientPackageHandler = [this](void* pkg, size_t size){
                //派发消息
                mDispatcher->HandleMessage(nullptr, pkg, size);
            };

            mClient = std::make_shared<MMFNetwork::Client>(
                mRemoteIp,
                mRemotePort,
                bufferSize,
                clientErrorHandler,
                clientStatusHandler,
                clientAsyncHandler,
                clientPackageHandler,
                family,
                true
            );

            mClient->Start();
        }
        catch(boost::system::error_code err)
        {
            std::string msg = err.message();
            return false;
        }
        
        return true;
    }

    void RpcClient::Stop()
    {
        mClient->Stop();
    }

    bool RpcClient::Send(void* buff, uint32_t count)
    {
        return mClient->Send(buff, count);
    }

    bool RpcClient::Recv(void* buff, uint32_t count)
    {
        return mClient->Recv(buff, count);
    }

    bool RpcClient::RecvPkg(void* buff, uint32_t count)
    {
        if (count < 12)
            return false;
        bool flag = Recv(buff, 12);
        if (!flag)
            return false;
        MMFNetwork::MMFMessageHeader* head = (MMFNetwork::MMFMessageHeader*)buff;
        if (count < head->mDataBytes)
            return false;
        int readCount = head->mDataBytes - 12;
        flag = Recv((char*)(buff) + 12, readCount);
        return flag;
    }

    std::shared_ptr<MMFNetwork::BinaryDispatch> RpcClient::Dispatcher()
    {
        return mDispatcher;
    }

    std::shared_ptr<MMFNetwork::Client> RpcClient::Client()
    {
        return mClient;
    }
}